﻿using AiFrame.InterfaceLib.Data.Patterns;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections;
using System.Collections.Generic;
using Moq;

namespace InterfaceLib.Tests
{
    
    
    /// <summary>
    ///Dies ist eine Testklasse für "ObservableCollectionTest" und soll
    ///alle ObservableCollectionTest Komponententests enthalten.
    ///</summary>
    [TestClass()]
    public class ObservableCollectionTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Ruft den Testkontext auf, der Informationen
        ///über und Funktionalität für den aktuellen Testlauf bietet, oder legt diesen fest.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Zusätzliche Testattribute
        // 
        //Sie können beim Verfassen Ihrer Tests die folgenden zusätzlichen Attribute verwenden:
        //
        //Mit ClassInitialize führen Sie Code aus, bevor Sie den ersten Test in der Klasse ausführen.
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Mit ClassCleanup führen Sie Code aus, nachdem alle Tests in einer Klasse ausgeführt wurden.
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Mit TestInitialize können Sie vor jedem einzelnen Test Code ausführen.
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Mit TestCleanup können Sie nach jedem einzelnen Test Code ausführen.
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///Ein Test für "ObservableCollection`1-Konstruktor"
        ///</summary>
        public void ObservableCollectionConstructorTestHelper<T>()
        {
            ObservableCollection<T> target = new ObservableCollection<T>();
            Assert.AreEqual(0, target.Count);
        }

        [TestMethod()]
        public void ObservableCollectionConstructorTest()
        {
            ObservableCollectionConstructorTestHelper<GenericParameterHelper>();
        }

        /// <summary>
        ///Ein Test für "Add"
        ///</summary>
        public void AddTestHelper<T>()
        {
            ObservableCollection<T> target = new ObservableCollection<T>();
            T item = default(T); 
            target.Add(item);
            Assert.AreEqual(0, target.IndexOf(item));
        }

        [TestMethod()]
        public void AddTest()
        {
            AddTestHelper<GenericParameterHelper>();
        }

        /// <summary>
        ///Ein Test für "BeginUpdate"
        ///</summary>
        public void BeginUpdateTestHelper<T>()
        {
            ObservableCollection<T> target = new ObservableCollection<T>();
            target.BeginUpdate();

            var observerMock = new Mock<IObserver>();
            target.RegisterObserver(observerMock.Object);
            target.EndUpdate();

            observerMock.Verify(o=>o.NotifyChanges(target, null));
        }

        [TestMethod()]
        public void BeginUpdateTest()
        {
            BeginUpdateTestHelper<GenericParameterHelper>();
        }


        /// <summary>
        ///Ein Test für "Fill"
        ///</summary>
        public void FillTestHelper<T>()
        {
            ObservableCollection<T> target = new ObservableCollection<T>();
            ObservableCollection<T> list = new ObservableCollection<T>();

            target.Add(default(T));

            T item1 = default(T);
            T item2 = default(T);

            list.Add(item1);
            list.Add(item2);

            var observerMock = new Mock<IObserver>();
            target.RegisterObserver(observerMock.Object);
            target.Fill(list);

            observerMock.Verify(o=>o.NotifyChanges(target, null), Times.Once());
            Assert.AreNotEqual(-1, target.IndexOf(item1));
            Assert.AreNotEqual(-1, target.IndexOf(item2));
        }

        [TestMethod()]
        public void FillTest()
        {
            FillTestHelper<GenericParameterHelper>();
        }

        /// <summary>
        ///Ein Test für "GetEnumerator"
        ///</summary>
        public void GetEnumeratorTestHelper<T>()
        {
            ObservableCollection<T> target = new ObservableCollection<T>();

            T item1 = default(T);
            T item2 = default(T);

            target.Add(item1);
            target.Add(item2);

            IEnumerator enumerator = target.GetEnumerator();

            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsTrue(enumerator.MoveNext());
            Assert.IsFalse(enumerator.MoveNext());
        }

        [TestMethod()]
        public void GetEnumeratorTest()
        {
            GetEnumeratorTestHelper<GenericParameterHelper>();
        }

        /// <summary>
        ///Ein Test für "IndexOf"
        ///</summary>
        public void IndexOfTestHelper<T>() where T : new()
        {
            ObservableCollection<T> target = new ObservableCollection<T>();
            T item1 = new T();

            target.Add(item1);

            Assert.AreEqual(0, target.IndexOf(item1));
        }

        [TestMethod()]
        public void IndexOfTest()
        {
            IndexOfTestHelper<GenericParameterHelper>();
        }

        /// <summary>
        ///Ein Test für "NotifyObservers"
        ///</summary>
        public void NotifyObserversTestHelper<T>()
        {
            ObservableCollection<T> target = new ObservableCollection<T>();

            var observerMock = new Mock<IObserver>();
            target.RegisterObserver(observerMock.Object);

            target.NotifyObservers(null);
            observerMock.Verify(o=>o.NotifyChanges(target, null));
        }

        [TestMethod()]
        public void NotifyObserversTest()
        {
            NotifyObserversTestHelper<GenericParameterHelper>();
        }
        

        /// <summary>
        ///Ein Test für "Remove"
        ///</summary>
        public void RemoveTestHelper<T>() where T : new()
        {
            ObservableCollection<T> target = new ObservableCollection<T>(); 

            T item1 = new T();
            target.Add(item1);

            Assert.IsTrue(target.Count == 1);

            target.Remove(item1);

            Assert.IsTrue(target.Count == 0);
        }

        [TestMethod()]
        public void RemoveTest()
        {
            RemoveTestHelper<GenericParameterHelper>();
        }

        /// <summary>
        ///Ein Test für "RemoveAt"
        ///</summary>
        public void RemoveAtTestHelper<T>() where T : new()
        {
            ObservableCollection<T> target = new ObservableCollection<T>(); 
            T item1 = new T();

            target.Add(item1);
            Assert.IsTrue(target.Count == 1);
            target.RemoveAt(0);
            Assert.IsTrue(target.Count == 0);
        }

        [TestMethod()]
        public void RemoveAtTest()
        {
            RemoveAtTestHelper<GenericParameterHelper>();
        }
        
      
        /// <summary>
        ///Ein Test für "UnregisterObserver"
        ///</summary>
        public void UnregisterObserverTestHelper<T>() where T : new()
        {
            ObservableCollection<T> target = new ObservableCollection<T>();

            T item1 = new T();
            
            var observerMock = new Mock<IObserver>();
            target.RegisterObserver(observerMock.Object);

            target.Add(item1);
            observerMock.Verify(o=>o.NotifyChanges(target, item1));

            target.UnregisterObserver(observerMock.Object);
            target.Remove(item1);

            observerMock.Verify(o=>o.NotifyChanges(target, null), Times.Never());
        }

        [TestMethod()]
        public void UnregisterObserverTest()
        {
            UnregisterObserverTestHelper<GenericParameterHelper>();
        }

        /// <summary>
        ///Ein Test für "Count"
        ///</summary>
        public void CountTestHelper<T>()
        {
            ObservableCollection<T> target = new ObservableCollection<T>();

            T item1 = default(T);
            T item2 = default(T);

            target.Add(item1);
            target.Add(item2);

            Assert.AreEqual(2, target.Count);
        }

        [TestMethod()]
        public void CountTest()
        {
            CountTestHelper<GenericParameterHelper>();
        }

        /// <summary>
        ///Ein Test für "Item"
        ///</summary>
        public void ItemTestHelper<T>()
        {
            ObservableCollection<T> target = new ObservableCollection<T>();

            T item1 = default(T);
            T item2 = default(T);

            target.Add(item1);
            target.Add(item2);

            Assert.AreEqual(item1, target[0]);
            Assert.AreEqual(item2, target[1]);

        }

        [TestMethod()]
        public void ItemTest()
        {
            ItemTestHelper<GenericParameterHelper>();
        }
    }
}
